package interpreter;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;

/**
 * Abstract class to group, identical functionalities of primitive shapes.
 * It is kind of template pattern, especially moveObject is a template method 
 */
abstract class PrimitiveAbstract {
	// Methods to override by the child
	protected abstract void createShape();
	public abstract void scale(double scaleX , double scaleY);
	public abstract PrimitiveAbstract clone();
	
	// Base variables
	String type;
	Shape shape;
	
	// Move the shape
	int posX, posY;
	public int getPosX() { return posX; }
	public int getPosY() { return posY; }
	final public void moveObject(int posX, int posY){
		this.posX = posX;
		this.posY = posY;
		createShape();
	}
	
	// Scale
	double scaleX = 1;
	double scaleY = 1;
	public double getScaleX() {
		return scaleX;
	}
	public double getScaleY() {
		return scaleY;
	}
		
	// Color change
	Color color = Color.black;
	final public void setColor(Color color) {
		this.color = color;
	}
	final public Color getColor(){
		return color;
	}
		
	// Line style
	/** Defines "shape modifier", line width */
	final BasicStroke stroke = new BasicStroke(2.0f);
	
	// Drawing
	final public void drawObject(Graphics g) {
		  Graphics2D g2D = (Graphics2D) g;
		  g2D.setStroke(stroke);
		  g2D.setColor(color);
		  g2D.draw(shape);
	}
	
	// Selecting
	boolean isSelected = false;
	final public boolean isSelected() {
		return isSelected;
	}
	final public void setSelected(boolean isSelected) {
		this.isSelected = isSelected;
	}
	
	/** Selected squares around the shape */
    final public void drawHighlightSquares(Graphics g) {
    	Graphics2D g2D = (Graphics2D) g;
    	
    	Rectangle2D r = getBoundsRectangle();
		double x = r.getX() - 15;
        double y = r.getY() -15 ;
        double w = r.getWidth() + 30;
        double h = r.getHeight() + 30;

        g2D.setColor(Color.black);

        g2D.fill(new Rectangle.Double(x - 3.0, y - 3.0, 6.0, 6.0));
        g2D.fill(new Rectangle.Double(x + w * 0.5 - 3.0, y - 3.0, 6.0, 6.0));
        g2D.fill(new Rectangle.Double(x + w - 3.0, y - 3.0, 6.0, 6.0));
        g2D.fill(new Rectangle.Double(x - 3.0, y + h * 0.5 - 3.0, 6.0, 6.0));
        g2D.fill(new Rectangle.Double(x + w - 3.0, y + h * 0.5 - 3.0, 6.0, 6.0));
        g2D.fill(new Rectangle.Double(x - 3.0, y + h - 3.0, 6.0, 6.0));
        g2D.fill(new Rectangle.Double(x + w * 0.5 - 3.0, y + h - 3.0, 6.0, 6.0));
        g2D.fill(new Rectangle.Double(x + w - 3.0, y + h - 3.0, 6.0, 6.0));       
     }
    
	final public Rectangle2D getBoundsRectangle(){
		Rectangle2D r = shape.getBounds2D();        
        return r;
	}
}
